/**
 * @file contour.h
 * @author 
 * @brief 多边形区域轮廓
 * @version 1.0
 * @date 2020-08-14
 * 
 * @copyright Copyright (c) 2020
 * 
 */

#pragma once
#include <vector>
#include <string>
#include "data_struct/geometry/Point.h"
#include <yaml-cpp/yaml.h>
#include "opencv2/imgproc/imgproc.hpp"

namespace behavior_controller
{
    class Contour
    {
    public:
        Contour(){};

        /**
         * @brief 轮廓内的点判断
         * 
         * @param point_in_local 输入的点
         * @return true 
         * @return false 
         */
        bool IsPointInShape(const PointF &point_in_local);
        /**
         * @brief 获取轮廓顶点
         * 
         * @return const std::vector<PointF>& 
         */
        const std::vector<PointF> &contour_points() const;
        /**
         * @brief 获取轮廓顶点
         * 
         * @return const std::vector<PointF>& 
         */
        std::vector<PointF> &contour_points();
        void resize(uint n);

        void ModifyContour(int id, const PointF point);
        void CreatCvShape(); 

    private:
        std::vector<PointF> contour_points_; //轮廓顶点
        std::vector<cv::Point2f> cv_contour;
        bool cv_creat=false;
    };

    class ContourAreas
    {
    public:
        Contour &robot_shape(); //读取Yaml文件中的轮廓区域
        Contour &front_area();
        Contour &back_area();

        /**
         * @brief 加载Yaml文件中的轮廓区域
         * 
         * @param contour_yaml_ 
         */
        void Load(const YAML::Node &contour_yaml_);

    private:
        Contour robot_shape_; //Yaml文件中的轮廓区域变量
        Contour front_area_;
        Contour back_area_;
    };

     extern ContourAreas contour_areas; //轮廓区域实例化
} // namespace behavior_controller

namespace YAML
{

    template <>
    struct convert<behavior_controller::Contour>
    {
        /**
         * @brief 定义从yaml文件中轮廓类型的编码过程，需要适配Contour类
         * 
         * @param shape 
         * @return YAML::Node 
         */
        static YAML::Node encode(const behavior_controller::Contour &shape)
        {
            YAML::Node node;
            int index = 0;
            char buff[30];
            for (auto vertex : shape.contour_points())
            {
                sprintf(buff, "point%d", index);
                node["contour_points"][buff]["x"] = vertex.x();
                node["contour_points"][buff]["y"] = vertex.y();
                index++;
            }
            return node;
        }

        /**
         * @brief 定义从yaml文件中轮廓类型的解码过程，需要适配Contour类
         * 
         * @param node 
         * @param shape 
         * @return true 
         * @return false 
         */
        static bool decode(const YAML::Node &node, behavior_controller::Contour &shape)
        {
            shape.contour_points().clear();
            size_t contour_size = node["contour_points"].size();
            shape.contour_points().reserve(contour_size);
            char buff[30];
            for (unsigned long index = 0; index < contour_size; index++)
            {
                sprintf(buff, "point%lu", index);
                shape.contour_points().emplace_back(
                    node["contour_points"][buff]["x"].as<double>(),
                    node["contour_points"][buff]["y"].as<double>());
            }
            return true;
        }
    };

} // namespace YAML